#include <linux/sched.h>
#include <linux/kernel.h>

struct super_block super_block[NR_SUPER];

int ROOT_DEV = 0;

struct super_block *get_super(int dev)
{
    struct super_block *s;

    if (!dev)
        return NULL;
    s = super_block;
    while (s < NR_SUPER + super_block)
        if (s->s_dev == dev)
            return s;
        else
            s++;
    return NULL;
}

static struct super_block *read_super(int dev)
{
    struct super_block *s;
    struct buffer_head *bh;

    if (!dev)
        return NULL;
    
    s = get_super(dev);
    if (s)  // 如果超级块信息已经被读入内存
        return s;
    for (s = super_block; ; s++) {
        if (s >= NR_SUPER + super_block)
            return NULL;    // 如果没有空闲的超级块结构体
        if (!s->s_dev)
            break;
    }
    s->s_dev = dev;
    bh = bread(dev, 1);
    if (!bh) {
        s->s_dev = 0;
        return NULL;
    }
    __asm__("cld"::);   // 不加这句，结构体赋值会出错
    *(struct d_super_block *)s = *((struct d_super_block *)bh->b_data);
    brelse(bh);
    if (s->s_magic != SUPER_MAGIC) {    // 如果超级块的数据有问题
        s->s_dev = 0;
        return NULL;
    }
    return s;
}

void mount_root(void)
{
    struct super_block *p;
    struct m_inode *mi;
    
    p = read_super(ROOT_DEV);
    if (!p)
        panic("Unable to mount root");
    mi = iget(ROOT_DEV, ROOT_INO);
    if (!mi)
        panic("Unable to read root i-node");
    printk("i_mode:     %x\r\n", mi->i_mode);
    printk("i_uid:      %x\r\n", mi->i_uid);
    printk("i_size:     %x\r\n", mi->i_size);
    printk("i_mtime:    %x\r\n", mi->i_mtime);
    printk("i_gid:      %x\r\n", mi->i_gid);
    printk("i_nlinks:   %x\r\n", mi->i_nlinks);
}